package com.apes.framework.api;

import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.rop.context.RopContextHolder;
import com.apes.framework.rop.session.SimpleSession;
import com.apes.framework.util.ApesConst;
import com.apes.framework.util.EventUtil;
import com.apes.framework.util.MapUtil;
import com.apes.framework.util.RopUtil;
import com.apes.oap.RopContext;
import com.apes.oap.RopRequestContext;
import com.apes.oap.impl.SimpleRopRequestContext;
import com.apes.oap.session.RopSessionHolder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 功能：
 *
 * @author xul
 * @create 2018-02-01 11:39
 */
public class DomainService {

    /**
     * 功能：ESB服务方法
     */
    public <T> T invoke(String method, Object body) {
        return invoke(method, ApesConst.METHOD_VERSION, body);
    }

    /**
     * 功能：发送MQ消息
     */
//    public static void publish(String topic, String description, Object body) {
//        MQUtil.publish(topic, description, MapUtil.mapped(body));
//    }

    /**
     * 功能：发送同步事件
     */
    public List sendSynEvent(String topic, Object body) {
        return EventUtil.sendSynEvent(this, topic, body);
    }

    /**
     * 功能：发送异步事件
     *
     * @param topic
     * @param body
     */
    public void sendAynEvent(String topic, Object body) {
        EventUtil.sendAynEvent(this, topic, body);
    }

    /*
     * Map构造
     */
    public static Map mapper(Object... items) {
        return MapUtil.mapper(items);
    }

    /*
     * mapping
     */
//    public static <T> T mapping(Object source, String configKey) {
//        return (T) new Mapping(configKey).convert(source);
//    }

    /**
     * 功能：ESB服务方法
     */
    private <T> T invoke(String method, String version, Object body) {
        RopContext ropContext = RopUtil.getRopContext();
        SimpleRopRequestContext context = new SimpleRopRequestContext(ropContext);
        context.addSession(RopSessionHolder.get());
        RopRequestContext localContext = RopContextHolder.get();
        if (localContext != null) {
            context.setRawRequestObject(localContext.getRawRequestObject());
            context.setRawResponseObject(localContext.getRawResponseObject());
        }
        context.setMethod(method);
        context.setVersion(version);
        SimpleRequest simpleRequest = new SimpleRequest();
        simpleRequest.setRopRequestContext(context);
        simpleRequest.setData(body);
        String topic = "event:esbRouter.innerCall";
        List results = sendSynEvent(topic, simpleRequest);
        if (results == null || results.isEmpty() || results.get(0) == null) return null;
        return (T) results.stream().findFirst().orElse(null);
    }

    /**
     * 功能：获取容器Bean
     */
    protected static <T> T getBean(Class<T> clazz) {
        return SpringManager.getBean(clazz);
    }

    protected SimpleSession getSession(SimpleRequest request) {
        return request.getSession();
    }

    protected <T> T getCurrentUser(SimpleRequest request) {
        return (T) request.getCurrentUser();
    }

    protected <T> T getPerson(SimpleRequest request) {
        return (T) request.getPerson();
    }

    protected <T> T getPersonId(SimpleRequest request) {
        return (T) request.getPersonId();
    }

    protected String getPostId(SimpleRequest request) {
        return request.getPostId();
    }

    protected <T> T getUser(Integer userId) {
        List<T> users = sendSynEvent("event:aut.user.findOne", MapUtil.mapper("id", userId));
        users.removeIf(user -> user == null);
        if (users == null || users.isEmpty()) return null;
        return users.stream().findFirst().get();
    }

    public <R> R paged(List content, int page, int size, Function func) {
        return paged(content, page, size, content.size(), func);
    }

    public <R> R paged(List content, int page, int size, long total, Function func) {
        Pageable pageable = PageRequest.of(page, size);
        int fromIndex = pageable.getPageSize() * pageable.getPageNumber();
        int toIndex = pageable.getPageSize() * (pageable.getPageNumber() + 1);
        if (toIndex > content.size()) toIndex = content.size();
        List result = content.subList(fromIndex, toIndex);
        if (func != null) {
            result = (List) result.stream().map(o -> func.apply(o)).collect(Collectors.toList());
        }
        return (R) new PageImpl(result, pageable, total);
    }
}
